/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jose.ibama;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.component.submenu.Submenu;

/**
 *
 * @author jose
 */
@ManagedBean(name = "rubricaMB")
@RequestScoped
public class RubricaMB {
    
    private Cargo cargo; 
    private Integer escolaridadeSelecionada; 
    private Integer gqSelecionada;
    private Integer pontosDesempenho;
    private Integer dependentesIRRF;
    private Integer anuenio; 
    private boolean associadoAsibama;
    private BigDecimal indicePrevidencia;
    private BigDecimal vpni; 
    private TabelaIbama tabela; 
    private List<TabelaIbama> tabelasIbama; 
    private TabelaIbama rubricaSelecionada; 

    public TabelaIbama getRubricaSelecionada() {
        return rubricaSelecionada;
    }

    public void setRubricaSelecionada(TabelaIbama rubricaSelecionada) {
        this.rubricaSelecionada = rubricaSelecionada;
    }
    
     
    public RubricaMB(){
        
        tabela = new TabelaIbama();
        tabelasIbama = new ArrayList<TabelaIbama>();
        
        vpni = new BigDecimal(0);
        indicePrevidencia = new BigDecimal(0.11);
        pontosDesempenho = 100; 
        dependentesIRRF = 0; 
        anuenio = 0;  
        gqSelecionada = 0; 
        
        escolaridadeSelecionada = 3; 
    }
    
    public List<TabelaIbama> getTabelasIbama() {
        return tabelasIbama;
    }

    public void setTabelasIbama(List<TabelaIbama> tabelasIbama) {
        this.tabelasIbama = tabelasIbama;
    }

    public TabelaIbama getTabela() {
        return tabela;
    }

    public void setTabela(TabelaIbama tabela) {
        this.tabela = tabela;
    }

    public Integer getDependentesIRRF() {
        return dependentesIRRF;
    }

    public void setDependentesIRRF(Integer dependentesIRRF) {
        this.dependentesIRRF = dependentesIRRF;
    }

    public boolean isAssociadoAsibama() {
        return associadoAsibama;
    }

    public void setAssociadoAsibama(boolean associadoAsibama) {
        this.associadoAsibama = associadoAsibama;
    }

    public BigDecimal getIndicePrevidencia() {
        return indicePrevidencia;
    }

    public void setIndicePrevidencia(BigDecimal indicePrevidencia) {
        this.indicePrevidencia = indicePrevidencia;
    }

    public BigDecimal getVpni() {
        return vpni;
    }

    public void setVpni(BigDecimal vpni) {
        this.vpni = vpni;
    }

    public Integer getAnuenio() {
        return anuenio;
    }

    public void setAnuenio(Integer anuenio) {
        this.anuenio = anuenio;
    }
    

    public Integer getPontosDesempenho() {
        return pontosDesempenho;
    }

    public void setPontosDesempenho(Integer pontosDesempenho) {
        this.pontosDesempenho = pontosDesempenho;
    }
    

    public Integer getGqSelecionada() {
        return gqSelecionada;
    }

    public void setGqSelecionada(Integer gqSelecionada) {
        this.gqSelecionada = gqSelecionada;
    }

    public Integer getEscolaridadeSelecionada() {
        return escolaridadeSelecionada;
    }

    public void setEscolaridadeSelecionada(Integer escolaridadeSelecionada) {
        this.escolaridadeSelecionada = escolaridadeSelecionada;
    }

    public Cargo getCargo() {
        return cargo;
    }

    public void setCargo(Cargo cargo) {
        this.cargo = cargo;
    }
   
    
    
    //métodos
    /**
     * Método para calcular o PSS, considerando se o servidor é do regime antigo ou funpresp
     * @param referencia Base de cálculo para desconto do PSS
     * @param aliquota Alíquota aplicada sobre a base de cálculo
     * @param ano Ano de referência de teto. Lembrando que haverá desconto de 11% até o teto, independente do regime escolhido. 
     * @return resposta: O valor do PSS
     */
    public BigDecimal calculaPSS(BigDecimal referencia, BigDecimal aliquota, Integer ano){
        BigDecimal teto = new BigDecimal(0);
        switch (ano){
           case 2010:
               teto = teto.add(new BigDecimal(3467.40));
               break;
           case 2011:
               teto = teto.add(new BigDecimal(3691.74));
               break;
           case 2012:
               teto = teto.add(new BigDecimal(3916.20));
               break;
           case 2013:
               teto = teto.add(new BigDecimal(4159));
               break;
           case 2014:
               teto = teto.add(new BigDecimal(4159));
               break;
           case 2015:
               teto = teto.add(new BigDecimal(4159));
               break;
       }
       if (referencia.doubleValue() <= teto.doubleValue()){
           referencia = referencia.multiply(new BigDecimal(0.11));
       }
       else{
           referencia = referencia.subtract(teto);
           referencia = referencia.multiply(aliquota);
           teto = teto.multiply(new BigDecimal(0.11));
           referencia = referencia.add(teto);
       }
       return referencia;
    }
    
    /**
     * Método para calcular o Imposto de Renda retido na fonte, 
     * de acordo com parâmetros de salário e número de dependentes
     * @param referencia Base de cálculo para o imposto de renda
     * @param ano Ano de tabela a ser utilizada para o cálculo do imposto de renda 
     * @param dependentes Número de dependentes para cálculo do IRRF a ser retido na fonte
     * @return resposta: o valor do IRRF a ser retido na fonte
     */
    public BigDecimal calculaIR(BigDecimal referencia, Integer ano, Integer dependentes)
            throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException{
        BigDecimal aliquota = new BigDecimal(0);
        BigDecimal parcelaADeduzir = new BigDecimal(0); 
        BigDecimal descontoDependentes = new BigDecimal(0); 
        BigDecimal resposta = new BigDecimal(0);
        
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/imposto_renda", "root", "testeroot"); 
        
        Statement stm = conn.createStatement();  
        if(ano < 2012) ano = 2012;
        ResultSet rs = stm.executeQuery("select aliquota, parcela_a_deduzir from aliquotas where ano <=" 
                + ano + " and piso <="  + referencia.doubleValue() + " and teto >=" + referencia.doubleValue() + " ORDER by ano desc limit 1"); 
        
        rs.next();
        aliquota = rs.getBigDecimal("aliquota");
        parcelaADeduzir = rs.getBigDecimal("parcela_a_deduzir");
        
       
        
        if(dependentes > 0){
            Statement stm2 = conn.createStatement();
            ResultSet rs2 = stm.executeQuery("select desconto from dependente where ano <=" + ano + " order by ano desc limit 1");
            rs2.next();
            descontoDependentes = rs2.getBigDecimal("desconto").multiply(new BigDecimal(dependentes));
            stm2.close();
            rs2.close();
        }
        stm.close();
        rs.close();   
        conn.close(); 
        aliquota = aliquota.divide(new BigDecimal(100));
        referencia = referencia.subtract(descontoDependentes);
        referencia = referencia.multiply(aliquota);
        referencia = referencia.subtract(parcelaADeduzir);
        if(referencia.doubleValue() > 0)return referencia; 
        else return new BigDecimal(0);
    }
    
    /**
     * Método que calcula o valor da contribuição para o Asibama, se filiado
     * @param referencia Base de cálculo para o desconto do Asibama
     * @param ehAssociado Calcula contribuição apenas se for filiado. 
     * Se não, retorna 0, pois não haverá desconto. 
     * @return o valor da contribuição para o Asibama (0,5% da remuneração)
     */
    public BigDecimal calculaAsibama(BigDecimal referencia, boolean ehAssociado){
        if(ehAssociado) return referencia.multiply(new BigDecimal(0.005)).setScale(2, RoundingMode.FLOOR);
        else return new BigDecimal(0); 
    }
    
    /**
     * Cria lista de vencimentos de acordo com a escolha do cargo
     * A consulta retorna apenas maior ou igual que 2 porque são estes os cargos fixos do Ibama, referindo-se outros códigos a 
     * rubricas alternativas(em desenvolimento)
     * @return lista de itens a serem impressos no combox padrão
     */
    public List recuperaCargos()throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException{
        List<Cargo> cargos = new ArrayList<Cargo>();
        
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ibama", "root", "testeroot"); 
        
        Statement stm = conn.createStatement();  
        ResultSet rs = stm.executeQuery("select * from cargos where cargo_escolaridade >= 2 order by cargo_nome, especialidade"); 
        
        while (rs.next()) {
            Cargo cargo = new Cargo();
            cargo.setCargoEscolaridade(rs.getInt("cargo_escolaridade"));
            cargo.setId_cargo(rs.getInt("id_cargo"));
            cargo.setEspecialidade(rs.getString("especialidade"));
            cargo.setCargoNome(rs.getString("cargo_nome"));
            cargos.add(cargo);
        }  
        conn.close(); 
        stm.close();
        rs.close();
        return cargos; 
    }
    
    public List recuperaEscolaridades()throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException{
        List<SubMenu> submenus = new ArrayList<SubMenu>();
        
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ibama", "root", "testeroot"); 
        
        Statement stm = conn.createStatement();  
        ResultSet rs = stm.executeQuery("select * from escolaridade where escolaridade=" + getEscolaridadeSelecionada()); 
        
        
        while (rs.next()) {
            SubMenu submenu = new SubMenu();
            submenu.setEscolaridade(rs.getInt("escolaridade"));
            submenu.setNome(rs.getString("nivel"));
            submenu.setValor(rs.getInt("valorGQ"));
          
            submenus.add(submenu);
        }  
        
        conn.close(); 
        stm.close();
        rs.close();
        return submenus;
    }

    
    public List<TabelaIbama> calculaSalario() throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException{
       
        
        //SELECT id_escolaridade, nivel, ano, valor, pontoGDAEM, gqI, gqII FROM ibama.vencimentos where id_escolaridade = 3 order by ano, nivel desc;
         Class.forName("com.mysql.jdbc.Driver").newInstance();
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/ibama", "root", "testeroot"); 
        
        Statement stm = conn.createStatement();  
        ResultSet rs = stm.executeQuery("SELECT id_escolaridade, nivel, ano, valor, pontoGDAEM, gqI, gqII FROM ibama.vencimentos where id_escolaridade = " +getEscolaridadeSelecionada() +" order by ano, nivel desc"); 
        Integer identificacao = new Integer(0);
        
        while (rs.next()) {
            TabelaIbama tabelaIbama = new TabelaIbama();
            tabelaIbama.setIdentificacao(identificacao);
            identificacao++;
            BigDecimal valorGQ = new BigDecimal(0);
            BigDecimal valorAnuenio =new BigDecimal(0);
            BigDecimal auxilioAlimentacao = new BigDecimal(0);
            BigDecimal salarioBruto = new BigDecimal(0);
            BigDecimal PSS = new BigDecimal(0);
            BigDecimal IRRF = new BigDecimal(0);
            BigDecimal desconto = new BigDecimal(0);
            BigDecimal baseIRPF = new BigDecimal(0);
            BigDecimal basePSS = new BigDecimal(0);
            BigDecimal baseAsibama = new BigDecimal(0);
            tabelaIbama.setAno(rs.getInt("ano")); 
            auxilioAlimentacao = calculaAuxilioAlimentacao(rs.getInt("ano"));
            tabelaIbama.setAuxilioAlimentacao(auxilioAlimentacao);
            
            switch(getGqSelecionada()){
                case 1:
                    valorGQ = rs.getBigDecimal("gqI");
                    break;
                case 2: 
                    valorGQ = rs.getBigDecimal("gqII"); 
                    break;
                default:
                    valorGQ = new BigDecimal(0); 
                    break;
            }
            
            tabelaIbama.setGq(valorGQ);
            tabelaIbama.setNivel(rs.getInt("nivel"));
            tabelaIbama.setNumeroPontos(getPontosDesempenho());
            tabelaIbama.setPontoGratificacao(rs.getBigDecimal("pontoGDAEM"));
            tabelaIbama.setValorGratificacao(rs.getBigDecimal("pontoGDAEM").multiply(new BigDecimal(getPontosDesempenho())));
            tabelaIbama.setVpni(vpni);
            tabelaIbama.setVencimento(rs.getBigDecimal("valor").setScale(2,RoundingMode.FLOOR));
            tabelaIbama.setAnuenio(rs.getBigDecimal("valor").multiply(new BigDecimal(anuenio).divide(new BigDecimal(100))));
            salarioBruto = salarioBruto.add(rs.getBigDecimal("valor")).add(valorGQ).add(new BigDecimal(getPontosDesempenho()).multiply(rs.getBigDecimal("pontoGDAEM")))
                    .add(rs.getBigDecimal("valor").multiply(new BigDecimal(anuenio).divide(new BigDecimal(100)))).add(vpni).add(auxilioAlimentacao);
            salarioBruto = salarioBruto.setScale(2,RoundingMode.FLOOR);
            tabelaIbama.setSalarioBruto(salarioBruto);
            PSS = PSS.add(calculaPSS((salarioBruto.subtract(auxilioAlimentacao)), getIndicePrevidencia(), rs.getInt("ano")));
            PSS = PSS.setScale(2,RoundingMode.FLOOR);
            tabelaIbama.setValorPSS(PSS);
            baseIRPF = salarioBruto.subtract(PSS).subtract(auxilioAlimentacao); 
            IRRF = calculaIR(baseIRPF, rs.getInt("ano"), getDependentesIRRF());
            IRRF = IRRF.setScale(2,RoundingMode.FLOOR);
            tabelaIbama.setValorIR(IRRF);
            tabelaIbama.setValorAsibama(calculaAsibama(salarioBruto.subtract(auxilioAlimentacao), isAssociadoAsibama()));
            desconto = calculaAsibama(salarioBruto.subtract(auxilioAlimentacao), isAssociadoAsibama()).add(PSS).add(IRRF);
            desconto = desconto.setScale(2, RoundingMode.FLOOR);
            tabelaIbama.setDescontos(desconto);
            tabelaIbama.setSalarioLiquido(salarioBruto.subtract(desconto));
            tabelasIbama.add(tabelaIbama); 
            
            //se chegou no início da carreira, representado pelo nível igual a 1, adiciona mais uma linha, referente ao salário inicial da carreira, com GDAEM fixada em 80 pontos
            if(rs.getInt("nivel") == 1){
                TabelaIbama tabelaIbama2 = new TabelaIbama();
                tabelaIbama2.setIdentificacao(identificacao);
                 identificacao++;
                 tabelaIbama2.setVencimento(rs.getBigDecimal("valor").setScale(2,RoundingMode.FLOOR));
                tabelaIbama2.setAno(rs.getInt("ano")); 
                tabelaIbama2.setAuxilioAlimentacao(auxilioAlimentacao);
                tabelaIbama2.setGq(valorGQ);
                tabelaIbama2.setNivel(0);
                tabelaIbama2.setNumeroPontos(80);
                tabelaIbama2.setPontoGratificacao(rs.getBigDecimal("pontoGDAEM"));
                tabelaIbama2.setValorGratificacao(rs.getBigDecimal("pontoGDAEM").multiply(new BigDecimal(80)));
                tabelaIbama2.setVpni(vpni);
                tabelaIbama2.setAnuenio(valorAnuenio);
                salarioBruto = salarioBruto.subtract((rs.getBigDecimal("pontoGDAEM").multiply(new BigDecimal(20))));
                tabelaIbama2.setSalarioBruto(salarioBruto);
                PSS = PSS.multiply(new BigDecimal(0));
                PSS = PSS.add(calculaPSS((salarioBruto.subtract(auxilioAlimentacao)), getIndicePrevidencia(), rs.getInt("ano")));
                PSS = PSS.setScale(2,RoundingMode.FLOOR);
                tabelaIbama2.setValorPSS(PSS);
                IRRF = calculaIR(salarioBruto.subtract(auxilioAlimentacao.add(PSS)), rs.getInt("ano"), getDependentesIRRF());
                IRRF = IRRF.setScale(2,RoundingMode.FLOOR);
                tabelaIbama2.setValorIR(IRRF);
                tabelaIbama2.setValorAsibama(calculaAsibama(salarioBruto.subtract(auxilioAlimentacao), isAssociadoAsibama()));
                desconto = calculaAsibama(salarioBruto.subtract(auxilioAlimentacao), isAssociadoAsibama()).add(PSS).add(IRRF);
                desconto = desconto.setScale(2, RoundingMode.FLOOR);
                tabelaIbama2.setDescontos(desconto);
                tabelaIbama2.setSalarioLiquido(salarioBruto.subtract(desconto));
                tabelasIbama.add(tabelaIbama2); 
                
            }
        }
        stm.close();
        rs.close();
        conn.close();
        return tabelasIbama; 
    }
    
    /**
     * @param ano O ano em que vai ser oferecido o benefício do auxílio alimentação
     * retorna o valor do auxío devido
     */
    public BigDecimal calculaAuxilioAlimentacao(Integer ano){
        if(ano >= 2013) return new BigDecimal(373); 
        else return new BigDecimal(304); 
    }
}
